package estatistico.presenter;

import estatistico.util.LeitorJar;
import estatistico.view.MainView;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import plugin.PluginBase;

public final class MainPresenter {

    private ArrayList<Double> numeros = new ArrayList<Double>();
    private MainView view;

    public MainPresenter() throws MalformedURLException, IOException, ClassNotFoundException {

        setAparencia();

        view = new MainView();
        
        configPluginMenu();

        view.getMnCadastrar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ManterNumerosPresenter presenterNumeros = new ManterNumerosPresenter(numeros);
                presenterNumeros.dispose();
            }
        });

        view.setLocationRelativeTo(null);
        view.setVisible(true);
    }

    private void configPluginMenu() throws MalformedURLException, IOException, ClassNotFoundException {
        LeitorJar leitor = new LeitorJar(new File("").getAbsolutePath() + "/src/estatistico/modules/");
        Map<String, Map.Entry<String, URL>> classesPlugin = leitor.getClassesPlugin();

        for (Map.Entry<String, Map.Entry<String, URL>> entry : classesPlugin.entrySet()) {
            String nomeMenu = entry.getKey();
            Map.Entry<String, URL> classe = entry.getValue();
            view.getJmPrincipal().add(new JMenuItem(nomeMenu));

            ActionListener ac = createListener(classe, numeros);
            view.getJmPrincipal().getItem(view.getJmPrincipal().getItemCount() - 1).addActionListener(ac);
        }
    }

    private void setAparencia() {
        String lookAndFeel = UIManager.getSystemLookAndFeelClassName();
        try {
            UIManager.setLookAndFeel(lookAndFeel);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private ActionListener createListener(final Map.Entry<String, URL> classe, final ArrayList numeros) {
        return new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    URLClassLoader child = new URLClassLoader(new URL[]{classe.getValue()}, this.getClass().getClassLoader());
                    Class definicaoClasse = Class.forName(classe.getKey(), true, child);
                    Constructor representacaoConstrutor;
                    Class[] intArgsClass = new Class[]{ArrayList.class};
                    representacaoConstrutor = definicaoClasse.getConstructor(intArgsClass);

                    Object[] intArgs = new Object[]{numeros};

                    PluginBase plugin = (PluginBase) representacaoConstrutor.newInstance(intArgs);

                } catch (NoSuchMethodException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (SecurityException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (InstantiationException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (IllegalAccessException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (IllegalArgumentException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (InvocationTargetException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                } catch (ClassNotFoundException ex) {
                    JOptionPane.showMessageDialog(null, "Falha: " + ex.getCause().getLocalizedMessage() + "\n\n" + ex.getMessage());
                }
            }
        };
    }

    public void setNumeros(ArrayList<Double> numeros) {
        this.numeros = numeros;
    }
}
